<?php

namespace maotool\util;

class NetWorkUtil
{

    /**
     * 获取MAC地址
     * @return string|null
     */
    public static function mac()
    {
        $macAddress = null;
        if (OsUtil::isWindows()) {
            $output = [];
            exec('getmac', $output);
            foreach ($output as $line) {
                if (preg_match('/([0-9A-F]{2}[:-]){5}([0-9A-F]{2})/', $line, $matches)) {
                    $macAddress = $matches[0];
                    break;
                }
            }
        } elseif (OsUtil::isUnix()) {
            $output = [];
            exec('ifconfig', $output);
            foreach ($output as $line) {
                if (preg_match('/([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})/', $line, $matches)) {
                    $macAddress = $matches[0];
                    break;
                }
            }
        }
        return $macAddress;
    }

    /**
     * 获取当前计算机的IP地址
     * @return string|null
     */
    public static function ip()
    {
        $ipAddress = null;

        if (OsUtil::isWindows()) {
            // Windows 系统使用 ipconfig 命令
            $output = [];
            exec('ipconfig', $output);
            foreach ($output as $line) {
                // 匹配 IPv4 地址，支持多种格式
                if (preg_match('/IPv4 Address\s*:\s*(\d+\.\d+\.\d+\.\d+)/', $line, $matches)) {
                    $ipAddress = $matches[1];
                    break;
                }
            }
        } elseif (OsUtil::isUnix()) {
            // Unix/Linux 系统使用 ip addr show 命令
            $output = [];
            exec('ip addr show', $output);
            foreach ($output as $line) {
                // 匹配 inet 地址，排除本地回环地址
                if (preg_match('/inet (\d+\.\d+\.\d+\.\d+)/', $line, $matches)) {
                    $ipAddress = $matches[1];
                    if ($ipAddress !== '127.0.0.1') { // 排除本地回环地址
                        break;
                    }
                }
            }
        }

        // 如果仍未获取到 IP 地址，尝试使用 PHP 的 socket 方法
        if (!$ipAddress) {
            $ipAddress = self::getIpAddressUsingSocket();
        }

        return $ipAddress;
    }

    /**
     * 使用 socket 扩展获取 IP 地址
     * @return string|null
     */
    private static function getIpAddressUsingSocket()
    {
        $ipAddress = null;
        // 尝试通过 DNS 解析获取本机 IP 地址
        if (function_exists('gethostbyname')) {
            $hostname = gethostname();
            if ($hostname) {
                $ipAddress = gethostbyname($hostname);
                if ($ipAddress === $hostname) {
                    $ipAddress = null; // 如果解析失败，返回 null
                }
            }
        }
        return $ipAddress;
    }

    /**
     * 获取本机网关地址
     * @return string|null
     */
    public static function gateway()
    {
        $gateway = null;
        if (OsUtil::isWindows()) {
            // Windows 系统使用 route print 命令
            $output = [];
            exec('route print 0.0.0.0', $output);
            foreach ($output as $line) {
                if (preg_match('/0\.0\.0\.0\s+0\.0\.0\.0\s+(\d+\.\d+\.\d+\.\d+)/', $line, $matches)) {
                    $gateway = $matches[1];
                    break;
                }
            }
        } elseif (OsUtil::isUnix()) {
            // Unix/Linux 系统使用 ip route show 命令
            $output = [];
            exec('ip route show default', $output);
            foreach ($output as $line) {
                if (preg_match('/default via (\d+\.\d+\.\d+\.\d+)/', $line, $matches)) {
                    $gateway = $matches[1];
                    break;
                }
            }
        }
        return $gateway;
    }

    /**
     * 获取本机 DNS 服务器地址
     * @return array|null
     */
    public static function dns()
    {
        $dnsServers = [];

        if (OsUtil::isWindows()) {
            // Windows 系统使用 ipconfig /all 命令
            $output = [];
            exec('ipconfig /all', $output);
            foreach ($output as $line) {
                // 扩展正则表达式以匹配更多格式
                if (preg_match('/DNS Servers\s*:\s*(\d+\.\d+\.\d+\.\d+)/i', $line, $matches)) {
                    $dnsServers[] = $matches[1];
                }
            }
        } elseif (OsUtil::isUnix()) {
            // Unix/Linux 系统解析 /etc/resolv.conf 文件
            $resolvConf = @file('/etc/resolv.conf');
            if ($resolvConf) {
                foreach ($resolvConf as $line) {
                    // 扩展正则表达式以匹配更多格式
                    if (preg_match('/nameserver\s+(\d+\.\d+\.\d+\.\d+)/i', $line, $matches)) {
                        $dnsServers[] = $matches[1];
                    }
                }
            }
        }

        return !empty($dnsServers) ? $dnsServers : null;
    }

    /**
     * 判断是否有外网连接
     * @return bool
     */
    public static function hasInternet()
    {
        $url = 'https://www.bing.com';
        $timeout = 5;
        $context = stream_context_create([
            'http' => ['timeout' => $timeout],
        ]);
        $response = @file_get_contents($url, false, $context);
        return $response !== false;
    }

}
